
interface FilterHander {
    (event: KeyboardEvent): number | undefined;
}

export interface FilterSorter {
    hander: (event: KeyboardEvent)=>number
    sort: number
}

const incode = (value: number, code: number): boolean=>{
    return (value & code) == code
}

class keyEvnet {
    static CODES = {
        close: 0b1, // 立刻结束
        preventDefault: 0b10, // 时间冒泡
        groupAfterClose: 0b100, // 完成当前组的过滤器后返回
    }
    beginFilter: (FilterHander|FilterSorter)[] = [];
    afterFilter: (FilterHander|FilterSorter)[] = [];
    onclick(event: KeyboardEvent){
        let groupCose = false;
        let beginSort  = (<FilterSorter[]>this.beginFilter.filter(filter => 'sort' in filter? filter : null )).sort((a,b)=>a.sort - b.sort);
        for (let sortHandel of beginSort) {
            let code = sortHandel.hander(event);
            if(incode(code , keyEvnet.CODES.preventDefault)){
                event.preventDefault();
            }
            if(incode(code, keyEvnet.CODES.groupAfterClose)){
                groupCose = true;
            }
            if(incode(code , keyEvnet.CODES.close)){
                return;
            }
        }
        if(groupCose){
            return;
        }
        let begin = <FilterHander[]>this.beginFilter.filter(filter => 'sort' in filter?  null : filter );
        for (let hander of begin) {
            let code = hander(event);
            if(code != undefined){
                if(incode(code , keyEvnet.CODES.preventDefault)){
                    event.preventDefault();
                }
                if(incode(code, keyEvnet.CODES.groupAfterClose)){
                    groupCose = true;
                }
                if(incode(code , keyEvnet.CODES.close)){
                    return;
                }
            }
        }
        if(groupCose){
            return;
        }

        let afterSort  = (<FilterSorter[]>this.afterFilter.filter(filter => 'sort' in filter? filter : null )).sort((a,b)=>a.sort - b.sort);
        for (let sortHandel of afterSort) {
            let code = sortHandel.hander(event);
            if(incode(code , keyEvnet.CODES.preventDefault)){
                event.preventDefault();
            }
            if(incode(code, keyEvnet.CODES.groupAfterClose)){
                groupCose = true;
            }
            if(incode(code , keyEvnet.CODES.close)){
                return;
            }
        }
        if(groupCose){
            return;
        }
        let after = <FilterHander[]>this.afterFilter.filter(filter => 'sort' in filter?  null : filter );
        for (let hander of after) {
            let code = hander(event);
            if(code != undefined){
                if(incode(code , keyEvnet.CODES.preventDefault)){
                    event.preventDefault();
                }
                if(incode(code, keyEvnet.CODES.groupAfterClose)){
                    groupCose = true;
                }
                if(incode(code , keyEvnet.CODES.close)){
                    return;
                }
            }
        }
        if(groupCose){
            return;
        }
    }

    async onclickAsync(event: KeyboardEvent){
        this.onclick(event);
    }
    
    addBeginFilter(filter: FilterHander | FilterSorter){
        this.beginFilter.push(filter);
    }
    addAfterFilter(filter: FilterHander | FilterSorter){
        this.afterFilter.push(filter);
    }
}

export default keyEvnet